﻿package treatBehavior
{
	import flash.geom.Point;
	public class KeepDisBehavior implements ITreatBehavior
	{
													//----------------------------------------------API------------------------------------
													//================ Properties ===============
													
													//================ Constants ================

													//================ Constructor ==============
		public function KeepDisBehavior(aVal:Array,dVal:Number,nVal:uint):void
		{
			arr=aVal;
			d=dVal;
			n=nVal;
		}													
													//================ Public Methods ===========
		public function getTreatArr():Array
		{
			//------------------------------------------------------------第一阶段：找到引导的数组(也就是找到前n+1个点)----------
																//---------------先找到初步的引导数组------------------------
			var guideArr:Array=new Array();
			var i:uint=0;
			var m:uint=0;//treatedArr的移动点；
			guideArr.push(arr[0]);//加入第一个点；
			guideLoop:for(var j:int=i;j<arr.length-1;j++)
			{
				i++;
				var tempDistance:Number=Point.distance(guideArr[m],arr[i]);
				if(tempDistance<d)
				{
					guideArr.push(arr[i]);
				}
				else if(tempDistance==d)
				{
					guideArr.push(arr[i]);
					break guideLoop;				
				}
				else if(tempDistance>d)
				{
					for(var x:uint=0;;x++)
					{
						if((Point.distance(arr[i-1],arr[i])-x*d/n/50)>=0)
						{
							var r:Number=(Point.distance(arr[i-1],arr[i])-x*d/n/50)/Point.distance(arr[i-1],arr[i]);
							var tempPoint:Point=Point.interpolate(arr[i-1],arr[i],r);
							if(Point.distance(guideArr[m],tempPoint)>=d)
							{
								guideArr.push(tempPoint);
								break guideLoop;
								//trace("step and insert");
								//trace(Point.distance(treatedArr[m],treatedArr[m+1]));
							}
						}else{
							guideArr.push(arr[i]);
							//trace("step!!");
							//trace(Point.distance(treatedArr[m],treatedArr[m+1]));
							break guideLoop;
						}
					}
				}
			}
																//------------由初步的数组找精确的引导数组，也是最终得到的数组的前n+1个值---。	
			var b:uint=0;
			var diet:Number=d/n;
			var q:uint=1;
			var treatedArr:Array;
			while(1)
			{
				q=1;
				m=0;
				treatedArr=new Array();
				treatedArr.push(guideArr[0]);			
				diet=d/n*((10000+b)/10000);
				wholeloop:while(q<guideArr.length)
				{
					var distance:Number=Point.distance(treatedArr[m],guideArr[q]);
					if(distance==diet)
					{
						treatedArr.push(guideArr[q]);
						m++;
						q++;
						continue wholeloop;
					}
					if(distance>diet)
					{
						var radio:Number=(distance-diet)/distance;
						treatedArr.push(Point.interpolate(treatedArr[m],guideArr[q],radio));
						m++;
						continue wholeloop;
					}
					if(distance<diet)
					{
						for(var g:int=q;g<guideArr.length-1;g++)
						{
							q++;
							tempDistance=Point.distance(treatedArr[m],guideArr[q]);
							if(tempDistance==diet)
							{
								treatedArr.push(guideArr[q]);
								m++;
								q++;
								continue wholeloop;
								break;				
							}
							if(tempDistance>diet)
							{
								break;
							}
						}
						if(Point.distance(treatedArr[m],guideArr[q])<diet)break wholeloop;
						for(var c:uint=0;;c++)
						{
							if((Point.distance(guideArr[q-1],guideArr[q])-c*diet/50)>=0)
							{
								var ra:Number=(Point.distance(guideArr[q-1],guideArr[q])-c*diet/50)/Point.distance(guideArr[q-1],guideArr[q]);
								tempPoint=Point.interpolate(guideArr[q-1],guideArr[q],ra);
								if(Point.distance(treatedArr[m],tempPoint)>=diet)
								{
									treatedArr.push(tempPoint);
									m++;
									continue wholeloop;
								}
							}else{
								treatedArr.push(guideArr[q]);
								m++;
								q++;							
								break;
							}
						}				
					}				
				}
				treatedArr[treatedArr.length-1].x=guideArr[guideArr.length-1].x;
				treatedArr[treatedArr.length-1].y=guideArr[guideArr.length-1].y;												
				if((treatedArr.length-1)==n&&(Point.distance(treatedArr[treatedArr.length-2],treatedArr[treatedArr.length-1])-diet<diet/20))
				{	
					break;
				}else if(treatedArr.length-1<n)
				{
					treatedArr=new Array();
					var distan:Number=Point.distance(guideArr[0],guideArr[guideArr.length-1]);
					var die:Number=distan/n;
					for(var h:uint=0;h<n;h++)
					{
						var poin:Point=Point.interpolate(guideArr[0],guideArr[guideArr.length-1],(distan-die*h)/distan);
						treatedArr.push(poin);
					}
					treatedArr.push(guideArr[guideArr.length-1]);
					break;
				}
				b++;
			}
			//----------------------------------------------------------------------------------------------------------------------------
			//---------------------------------------------------------------开始找到所有的点，使得一个点到距离这个点100间隔的点之间的距离等于直径。
			treatedArr.pop();
			m=0;
			var isOnline:Boolean=true;
			getDisLoop:while(i<arr.length)
			{
				var dis:Number=Point.distance(treatedArr[m],arr[i]);
				if(dis==d)
				{
					treatedArr.push(arr[i]);
					m++;
					i++;
					isOnline=false;
					continue getDisLoop;
				}
				if(dis>d)
				{
					if(isOnline==false)
					{
						for(var z:uint=0;;z++)
						{
							if((Point.distance(arr[i-1],arr[i])-z*d/50)>=0)
							{
								var tempRad:Number=(Point.distance(arr[i-1],arr[i])-z*d/50)/Point.distance(arr[i-1],arr[i]);
								var tempPo:Point=Point.interpolate(arr[i-1],arr[i],tempRad);
								if(Point.distance(treatedArr[m],tempPo)>=d)
								{
									treatedArr.push(tempPo);
									m++;
									isOnline=true;
									continue getDisLoop;
								}
							}else{
								treatedArr.push(arr[i]);
								m++;
								i++;
								isOnline=false;							
								break;
							}
						}
					}else if(isOnline==true)
					{
						for(var y:uint=0;;y++)
						{
							if((Point.distance(arr[i-1],arr[i])-y*d/50)>=0)
							{
								var tempR:Number=(Point.distance(treatedArr[treatedArr.length-1],arr[i])-y*d/50)/Point.distance(treatedArr[treatedArr.length-1],arr[i]);
								var tempP:Point=Point.interpolate(treatedArr[treatedArr.length-1],arr[i],tempR);
								if(Point.distance(treatedArr[m],tempP)>=d)
								{
									treatedArr.push(tempP);
									m++;
									continue getDisLoop;
								}
							}else{
								treatedArr.push(arr[i]);
								m++;
								i++;
								isOnline=false;							
								break;
							}
						}
						/*var rio:Number=(dis-d)/dis;
						treatedArr.push(Point.interpolate(treatedArr[treatedArr.length-1],arr[i],rio));
						trace()
						//trace(Point.distance(treatedArr[m],treatedArr[m+1]));
						m++;
						continue getDisLoop;*/
					}
				}
				if(dis<d)
				{
					if(i>=arr.length-1)break getDisLoop;
					for(var p:int=i;p<arr.length-1;p++)
					{
						i++;
						isOnline=false;
						var tempDis:Number=Point.distance(treatedArr[m],arr[i]);
						if(tempDis==d)
						{
							treatedArr.push(arr[i]);
							m++;
							i++;
							continue getDisLoop;
							break;				
						}
						if(tempDis>d)
						{
							break;
						}
					}
					/*for(var y:uint=0;;y++)
					{
						if((Point.distance(arr[i-1],arr[i])-y*d/50)>=0)
						{
							var tempR:Number=(Point.distance(arr[i-1],arr[i])-y*d/50)/Point.distance(arr[i-1],arr[i]);
							var tempP:Point=Point.interpolate(arr[i-1],arr[i],tempR);
							if(Point.distance(treatedArr[m],tempP)>=d)
							{
								treatedArr.push(tempP);				
								m++;
								continue getDisLoop;
							}
						}else{
							treatedArr.push(arr[i]);
							m++;
							i++;							
							break;
						}
					}*/				
				}				
			}
			for(var k:int=n;k<treatedArr.length;k++)
			{
				//trace(n);
				//trace(Point.distance(treatedArr[k-n],treatedArr[k]));
				//trace(Point.distance(treatedArr[k],treatedArr[k-1]));
			}
			trace(treatedArr);	
			return treatedArr;
		}
											//----------------------------------------------private--------------------------------												
													//================ Properties ===============
		private var arr:Array;
		private var d:Number;
		private var n:uint;
													//================ Private Methods ==========

													//================ Destroy ==================	
	}
}